<template>
  <div id="main_container">
    <div id="map_container" ref="mapContainer"></div>
    
    <!-- 搜索框 -->
    <div class="search-box">
      <input 
        type="text" 
        v-model="searchKeyword"
        placeholder="输入地点查询"
        @input="handleSearchInput"
      >
    </div>

    <!-- 天气信息 -->
    <div class="weather-box" v-if="weatherData">
      <h3 class="title">实时天气</h3>
      <hr>
      <ul v-if="!weatherLoading">
        <li>城市/区：{{ weatherData.city || weatherData.province }}</li>
        <li>天气：{{ weatherData.weather }}</li>
        <li>温度：{{ weatherData.temperature }}℃</li>
        <li>风向：{{ weatherData.windDirection }}</li>
        <li>风力：{{ weatherData.windPower }}级</li>
        <li>空气湿度：{{ weatherData.humidity }}%</li>
        <li>发布时间：{{ weatherData.reportTime }}</li>
      </ul>
      <div v-else class="loading">天气信息加载中...</div>
    </div>

    <!-- 路径输入 -->
    <div class="route-input">
      <div class="input-group">
        <label>起点:</label>
        <input 
          type="text" 
          v-model="startAddress.address"
          placeholder="地址"
          @blur="handleStartBlur"
        >
        <input 
          type="number" 
          v-model="startAddress.lng"
          placeholder="经度"
          step="0.000001"
          @change="validateCoordinate(startAddress)"
        >
        <input 
          type="number" 
          v-model="startAddress.lat"
          placeholder="纬度"
          step="0.000001"
          @change="validateCoordinate(startAddress)"
        >
      </div>

      <div class="input-group">
        <label>终点:</label>
        <input 
          type="text" 
          v-model="endAddress.address"
          placeholder="地址"
          @blur="handleEndBlur"
        >
        <input 
          type="number" 
          v-model="endAddress.lng"
          placeholder="经度"
          step="0.000001"
          @change="validateCoordinate(endAddress)"
        >
        <input 
          type="number" 
          v-model="endAddress.lat"
          placeholder="纬度"
          step="0.000001"
          @change="validateCoordinate(endAddress)"
        >
      </div>

      <div v-for="(waypoint, index) in waypoints" :key="index" class="input-group">
        <label>经过点 {{ index + 1 }}:</label>
        <input
          type="text"
          v-model="waypoint.address"
          placeholder="地址"
          @blur="handleWaypointBlur(index)"
        >
        <input
          type="number"
          v-model="waypoint.lng"
          placeholder="经度"
          step="0.000001"
          @change="validateWaypoint(index)"
        >
        <input
          type="number"
          v-model="waypoint.lat"
          placeholder="纬度"
          step="0.000001"
          @change="validateWaypoint(index)"
        >
        <button @click="removeWaypoint(index)" class="delete-btn">×</button>
      </div>

      <div class="button-group">
        <button @click="addWaypoint" class="add-btn">+ 添加途径点</button>
        <button @click="handleConfirmRoute" class="confirm-btn">规划路线</button>
        <button @click="handleReset" class="reset-btn">重置</button>
      </div>
    </div>

    <!-- 路线列表 -->
    <div class="route-list" v-if="polylines.length > 0">
      <h3 class="title">路线列表</h3>
      <ul>
        <li v-for="(polyline, index) in polylines" :key="index">
          <span>路线 {{ index + 1 }}</span>
          <button @click="removePolyline(index)" class="delete-btn">删除</button>
        </li>
      </ul>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";

// 地图相关响应式数据
const mapContainer = ref(null);
const map = ref(null);// 全局管理地图实例
const geocoder = ref(null);// 地理编码器单例
const placeSearch = ref(null);
const weatherPlugin = ref(null);// 天气插件单例
const autoComplete = ref(null);

// 输入数据
const startAddress = ref({ address: '', lng: '', lat: '', location: null });
const endAddress = ref({ address: '', lng: '', lat: '', location: null });
const waypoints = ref([{ address: '', lng: '', lat: '', location: null }]);

// 其他数据
const weatherData = ref(null);
const weatherLoading = ref(false);
const polylines = ref([]);
const searchKeyword = ref('');

// 安全配置
window._AMapSecurityConfig = {
  securityJsCode: "5f2edb6ad712b1faf7620939b2d098a1",
};

// 初始化地图
const initMap = async () => {
  try {
    const AMap = await AMapLoader.load({
      key: "ae609c314bae896486b2126b924b8a0c",
      version: "2.0",
      plugins: [
        "AMap.Scale", 
        "AMap.ToolBar", 
        "AMap.Geolocation", 
        "AMap.AutoComplete", 
        "AMap.PlaceSearch", 
        "AMap.Weather", 
        "AMap.Driving", 
        "AMap.Geocoder"
      ],
    });

    // 创建地图实例
    map.value = new AMap.Map(mapContainer.value, {
      viewMode: "3D",
      zoom: 15,
      center: [113.942170, 35.291228],
      mapStyle: 'amap://styles/dark'
    });

    // 初始化插件
    initPlugins(AMap);
    initControls(AMap);

  } catch (error) {
    console.error("地图初始化失败:", error);
  }
};

// 初始化插件
const initPlugins = (AMap) => {
  // 地理编码器
  geocoder.value = new AMap.Geocoder({ city: "全国" });
  
  // 输入提示
  autoComplete.value = new AMap.AutoComplete({ city: "全国" });
  
  // 地点搜索
  placeSearch.value = new AMap.PlaceSearch({ 
    map: map.value,
    pageSize: 5
  });

  // 天气插件
  weatherPlugin.value = new AMap.Weather();

  // 绑定自动完成事件
  AMap.event.addListener(autoComplete.value, "select", handlePlaceSelect);
};

// 初始化控件
const initControls = (AMap) => {
  map.value.addControl(new AMap.ToolBar());
  map.value.addControl(new AMap.Scale());
  map.value.addControl(new AMap.Geolocation({
    position: "RB",
    panToLocation: true
  }));
};

// 地址选择处理
const handlePlaceSelect = (e) => {
  if (e.poi?.location) {
    map.value.setCenter(e.poi.location);
    placeSearch.value.search(e.poi.name);
    fetchWeatherData(e.poi.name);
  }
};

// 获取天气数据
const fetchWeatherData = async (location) => {
  try {
    weatherLoading.value = true;
    weatherPlugin.value.getLive(location, (err, data) => {
      weatherData.value = err ? null : data;
    });
  } finally {
    weatherLoading.value = false;
  }
};

// 地址解析通用方法
const geocodeAddress = (address) => {
  return new Promise((resolve, reject) => {
    geocoder.value.getLocation(address, (status, result) => {
      if (status === "complete" && result.geocodes.length > 0) {
        resolve(result.geocodes[0].location);
      } else {
        reject(new Error("地址解析失败"));
      }
    });
  });
};

// 坐标验证
const validateCoordinate = async (target) => {
  if (target.lng && target.lat) {
    const lng = parseFloat(target.lng);
    const lat = parseFloat(target.lat);
    if (!isNaN(lng) && !isNaN(lat)) {
      target.location = { lng, lat };
      try {
        const address = await reverseGeocode({ lng, lat });
        target.address = address;
      } catch {
        target.address = "未知地址";
      }
    }
  }
};

// 逆地理编码
const reverseGeocode = (lnglat) => {
  return new Promise((resolve, reject) => {
    geocoder.value.getAddress(lnglat, (status, result) => {
      if (status === "complete" && result.regeocode) {
        resolve(result.regeocode.formattedAddress);
      } else {
        reject(new Error("逆地理编码失败"));
      }
    });
  });
};

// 处理地址输入
const handleAddressBlur = async (target) => {
  if (target.address) {
    try {
      const location = await geocodeAddress(target.address);
      target.location = location;
      target.lng = location.lng;
      target.lat = location.lat;
    } catch {
      target.location = null;
    }
  }
};

// 处理起点/终点输入
const handleStartBlur = () => handleAddressBlur(startAddress.value);
const handleEndBlur = () => handleAddressBlur(endAddress.value);
const handleWaypointBlur = (index) => handleAddressBlur(waypoints.value[index]);

// 路径规划
const handleConfirmRoute = async () => {
  try {
    // 验证起点
    const start = await getValidLocation(startAddress.value);
    // 验证终点
    const end = await getValidLocation(endAddress.value);
    // 验证途径点
    const waypointsLocations = await Promise.all(
      waypoints.value.map(wp => getValidLocation(wp))
    );

    // 创建驾车路线规划
    const driving = new AMap.Driving({
      map: map.value,
      policy: AMap.DrivingPolicy.LEAST_TIME
    });

    // 构造途经点
    const viaPoints = waypointsLocations
      .filter(loc => loc)
      .map(loc => new AMap.LngLat(loc.lng, loc.lat));

    // 执行路径规划
    driving.search(
      new AMap.LngLat(start.lng, start.lat),
      new AMap.LngLat(end.lng, end.lat),
      { waypoints: viaPoints },
      (status, result) => {
        if (status === "complete" && result.routes.length > 0) {
          const route = result.routes[0];
          const path = route.steps.flatMap(step => step.path);
          const polyline = new AMap.Polyline({
            path,
            isOutline: true,
            outlineColor: '#ffeeff',
            borderWeight: 2,
            strokeWeight: 5,
            strokeColor: '#0091ff',
            lineJoin: 'round'
          });
          polyline.setMap(map.value);
          polylines.value.push(polyline);
        } else {
          alert("路径规划失败，请检查输入");
        }
      }
    );

  } catch (error) {
    alert(error.message);
  }
};

// 获取有效坐标
const getValidLocation = async (target) => {
  // 优先使用手动输入的坐标
  if (target.lng && target.lat) {
    const lng = parseFloat(target.lng);
    const lat = parseFloat(target.lat);
    if (!isNaN(lng) && !isNaN(lat)) {
      return { lng, lat };
    }
  }
  
  // 次之使用地址解析
  if (target.address) {
    return geocodeAddress(target.address);
  }

  throw new Error("位置信息不完整");
};

// 清除路线
const clearRoute = () => {
  polylines.value.forEach(polyline => {
    polyline.setMap(null);
  });
  polylines.value = [];
};

// 删除单个路线
const removePolyline = (index) => {
  polylines.value[index].setMap(null);
  polylines.value.splice(index, 1);
};

// 重置功能
const handleReset = () => {
  startAddress.value = { address: '', lng: '', lat: '', location: null };
  endAddress.value = { address: '', lng: '', lat: '', location: null };
  waypoints.value = [{ address: '', lng: '', lat: '', location: null }];
  weatherData.value = null;
  clearRoute();
  map.value.setZoomAndCenter(15, [113.942170, 35.291228]);
};

// 途径点操作
const addWaypoint = () => {
  waypoints.value.push({ address: '', lng: '', lat: '', location: null });
};

const removeWaypoint = (index) => {
  waypoints.value.splice(index, 1);
};

// 搜索建议
const handleSearchInput = (e) => {
  autoComplete.value.search(e.target.value);
};

onMounted(initMap);
onUnmounted(() => {
  if (map.value) map.value.destroy();
});
</script>

<style scoped>
#main_container {
  position: relative;
  height: 100vh;
  width: 100%;
}

#map_container {
  width: 100%;
  height: 100%;
}

.search-box {
  position: absolute;
  top: 20px;
  left: 20px;
  z-index: 999;
  padding: 8px;
  border-radius: 8px;
}

.search-box input {
  width: 300px;
  padding: 8px 12px;
  border: 1px solid #555;
  border-radius: 4px;
  background: #333;
  color: white;
}

.weather-box {
  position: absolute;
  top: 20px;
  right: 20px;
  background: rgba(0, 0, 0, 0.8);
  padding: 16px;
  border-radius: 8px;
  color: white;
  min-width: 220px;
}

.weather-box .title {
  margin: 0 0 8px 0;
  color: #00a8ff;
}

.route-input {
  position: absolute;
  bottom: 20px;
  left: 20px;
  background: rgba(0, 0, 0, 0.8);
  padding: 16px;
  border-radius: 8px;
  color: white;
  max-width: 500px;
}

.input-group {
  display: grid;
  grid-template-columns: 80px repeat(3, 1fr) 40px;
  gap: 8px;
  align-items: center;
  margin-bottom: 8px;
}

.input-group label {
  font-size: 0.9em;
  color: #00a8ff;
}

.input-group input {
  padding: 6px;
  border: 1px solid #555;
  border-radius: 4px;
  background: #333;
  color: white;
  font-size: 0.9em;
}

input[type="number"] {
  width: 90px;
}

.button-group {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}

button {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: 0.3s;
}

.add-btn {
  background: #00a8ff;
  color: white;
}

.confirm-btn {
  background: #4CAF50;
  color: white;
}

.reset-btn {
  background: #f44336;
  color: white;
}

.delete-btn {
  background: transparent;
  color: #ff5555;
  font-size: 1.2em;
  padding: 0;
  min-width: 24px;
}

.loading {
  color: #888;
  font-style: italic;
}

.route-list {
  position: absolute;
  top: 20px;
  right: 20px;
  background: rgba(0, 0, 0, 0.8);
  padding: 16px;
  border-radius: 8px;
  color: white;
  min-width: 220px;
}

.route-list .title {
  margin: 0 0 8px 0;
  color: #00a8ff;
}

.route-list ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.route-list li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-size: 0.9em;
}

</style>